//
//  LiveViewController.swift
//  HinsLive
//
//  Created by haoxian on 2019/4/17.
//  Copyright © 2019 Hins. All rights reserved.
//

import UIKit
import IQKeyboardManagerSwift
import SocketIO
import Reachability


class LiveViewController: ViewController {
    
    private(set) lazy var dismissBtn: RoomIconButton = {
        let btn = RoomIconButton(imageFrame: CGRect(x: 8, y: 8, width: 16, height: 16))
        btn.backgroundColor = .roomGrayBackgroundColor
        btn.layer.cornerRadius = 16
        btn.layer.masksToBounds = true
        btn.setImage(R.image.room_btn_close(), for: .normal)
        btn.setImage(R.image.room_btn_close(), for: .highlighted)
        return btn
    }()
    
    private(set) lazy var contentView: LiveContentView = {
        let contentView = LiveContentView(masterName: room.name, avatarUrl: room.avatarURL)
        contentView.messagesView.dataSource = self
        contentView.chatToolView.sendSubject.subscribe(onNext: { [weak self] text in
            guard Network.isReachable else {
                self?.view.makeCenterMsg("网络不可用")
                return
            }
            self?.sendMessage(text)
        })
        .disposed(by: bag)
        return contentView
    }()
    
    private var chatMessages = [RoomChatMessage]()
    
    let manager = SocketManager(socketURL: URL(string: Network.socketHost)!, config: [.compress])
    
    private(set) lazy var socket = manager.defaultSocket
    
    let room: RoomInfo

    init(roomModel: RoomInfo) {
        room = roomModel
        super.init(nibName: nil, bundle: nil)
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        setupUI()
        registerNotification()
        handleSocketEvent()
        socket.connect()
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        IQKeyboardManager.shared.enableAutoToolbar = false
        IQKeyboardManager.shared.enable = false
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        view.endEditing(true)
        IQKeyboardManager.shared.enableAutoToolbar = true
        IQKeyboardManager.shared.enable = true
    }
    
    func socketJoinEvent(_ message: RoomChatMessage, _ ack: SocketAckEmitter) {
        received(message)
    }
    
    func socketLeaveEvent(_ message: RoomChatMessage, _ ack: SocketAckEmitter) {
        received(message)
    }
    
    func socketMessageEvent(_ message: RoomChatMessage, _ ack: SocketAckEmitter) {
        received(message)
    }
}

extension LiveViewController {
    func received(_ message: RoomChatMessage) {
        DispatchQueue.safeMainAsync {
            self.chatMessages.append(message)
            self.contentView.messagesView.reloadData()
            self.messageViewScrollToBottom()
        }
    }
    
    func entryTheRoom() {
        let user = AccountManager.share.user
        let message = RoomChatMessage.with {
            $0.uid = user.uid
            $0.name = user.name
            $0.content = "加入了房间"
            $0.ruid = room.ruid
        }
        socket.send(.join, message)
    }
    
    func leftTheRoom() {
        let user = AccountManager.share.user
        let message = RoomChatMessage.with {
            $0.uid = user.uid
            $0.name = user.name
            $0.content = "离开了房间"
            $0.ruid = room.ruid
        }
        socket.send(.leave, message)
    }
    
    func sendMessage(_ text: String) {
        let user = AccountManager.share.user
        let message = RoomChatMessage.with {
            $0.uid = user.uid
            $0.name = user.name
            $0.content = text
            $0.ruid = room.ruid
        }
        socket.send(.message, message)
    }
    
    func leaveAndDisconnet() {
        leftTheRoom()
        socket.disconnect()
        socket.removeAllHandlers()
    }
}

private extension LiveViewController {
    func setupUI() {
        view.backgroundColor = .black
        view.addSubview(contentView)
        contentView.snp.makeConstraints { (make) in
            make.edges.equalToSuperview()
        }
        view.addSubview(dismissBtn)
        dismissBtn.snp.makeConstraints { (make) in
            make.width.height.equalTo(32)
            make.centerY.equalTo(contentView.masterInfoView.snp.centerY)
            make.right.equalToSuperview().offset(-20)
        }
    }
    
    func registerNotification() {
        NotificationCenter.default.rx
            .notification(UIResponder.keyboardWillChangeFrameNotification)
            .subscribe(onNext: { [weak self] (notification) in
                guard let self = self,
                    let info = notification.userInfo,
                    let duration = info[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval,
                    let kbFrame = info[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return }
                if kbFrame.origin.y + 1 >= UIScreen.mainHeight {
                    self.contentView.hideChatTool(kbFrame, duration)
                } else {
                    self.messageViewScrollToBottom()
                    self.contentView.displayChatTool(kbFrame, duration)
                }
            })
            .disposed(by: bag)
        
        NotificationCenter.default.rx
            .notification(.reachabilityChanged)
            .subscribe(onNext: { [weak self] (notification) in
                guard let self = self, let reachability = notification.object as? Reachability else { return }
                switch reachability.currentReachabilityStatus() {
                case .NotReachable:
                    self.view.makeCenterMsg("网络不可用~")
                case .ReachableViaWWAN:
                    self.view.makeCenterMsg("当前正在使用蜂窝移动网络")
                default:
                    self.view.makeCenterMsg("当前正在使用Wifi网络")
                }
            })
            .disposed(by: bag)
    }
    
    func messageViewScrollToBottom() {
        guard chatMessages.count > 0 else { return }
        contentView.messagesViewScrollTo(IndexPath(row: chatMessages.count - 1, section: 0))
    }
    
    func handleSocketEvent() {
        socket.on(clientEvent: .connect) { [weak self] (_, _) in
            self?.entryTheRoom()
        }
        socket.on(event: .join, type: RoomChatMessage.self) { [weak self] (message, ack) in
            self?.socketJoinEvent(message, ack)
        }
        socket.on(event: .leave, type: RoomChatMessage.self) { [weak self] (message, ack) in
            self?.socketLeaveEvent(message, ack)
        }
        socket.on(event: .message, type: RoomChatMessage.self) { [weak self] (message, ack) in
            self?.socketMessageEvent(message, ack)
        }
    }
}

extension LiveViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return chatMessages.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "\(LiveViewController.self)", for: indexPath)
        if let messageCell = cell as? ChatMessageCell {
            let message = chatMessages[indexPath.row]
            let isMyself = message.uid == AccountManager.share.user.uid
            let isMaster = message.uid == room.ruid
            messageCell.setMessage(message: message, isMyself: isMyself, isMaster: isMaster)
        }
        return cell
    }
}
